import React, { useMemo } from 'react'
import { If } from '@sui/sui'

const AccessState = React.createContext({})

/**
 * 权限组件
 * @returns 
 */
export function Access(props) {
  const { children, accessible, fallback } = props
  return (
    <If condition={!!accessible} fallback={fallback}>{children}</If>
  )
}

/**
 * access provider
 * @param {*} props 
 * @returns 
 */
export function AccessProvider(props){
  const { children, access } = props;
  const value = useMemo(()=>({
    access
  }), [ access ])
  return <AccessState.Provider value={value}>
    {children}
  </AccessState.Provider>
}

/**
 * 获取access权限
 * @returns 
 */
export function useAccess(){
    const { access = {} } = React.useContext(AccessState)
    return access
}

/**
 * 获取access权限状态
 * @returns 
 */
export function useAccessState(){
  return React.useContext(AccessState)
}


/**
 * 修改并设置路由权限
 * @param {*} routes 
 * @param {*} access 
 * @param {*} parentUnaccessible
 */
/**
 * 修改并设置路由权限
 * @param {*} routes 
 * @param {*} access 
 * @param {*} strictMode
 * @param {*} parentUnaccessible
 */
 export function modifyRoutesByAccess(routes, access, strictMode,  parentUnaccessible){
  
  return [].concat(routes).map(route => {
      // 默认情况下，初始权限为已定义或继承上级权限
      let accessible = typeof route.unaccessible === 'boolean' ? !route.unaccessible : parentUnaccessible !== true;
      if ( strictMode ) { // 严格模式下，默认不通过
        accessible = false;
      }
      if ( route.access ) { // 当设置了权限，默认不通过，只有权限通过才能访问
          accessible = false;
          const accesses = [].concat(route.access)
          for (let index = 0; index < accesses.length; index++) {
              const accessName = accesses[index];
              if (access && access[accessName]) {
                  accessible = typeof access[accessName] === 'function' ? access[accessName](route) == true : true
                  break;
              }
          }
      }
      route.unaccessible = !accessible;
      if ( route.children && route.children.length ) {
        route.children = modifyRoutesByAccess(route.children, access, strictMode, route.unaccessible)
      }
      return route
  });
}

/**
 * 获取菜单paths
 * @param {*} menus 
 * @param {*} paths 
 */
export function getAccessMenusPaths(menus, paths){
  paths = paths || []
  if ( !menus || !menus.length ) {
    return paths
  }
  menus.forEach(menu=>{
    menu.path && paths.push(menu.path)
    if ( menu.children ) {
      getAccessMenusPaths(menu.children, paths)
    }
  })
  return paths
}

/**
 * 根据权限菜单处理路由权限
 * @param {*} routes 
 * @param {*} accessPaths 
 * @param {*} strictMode 
 * @param {*} parentUnaccessible 
 */
export function modifyRoutesByAccessMenus(routes, accessPaths, strictMode, parentUnaccessible){
  if ( accessPaths && accessPaths.length && routes && routes.length ) {
      routes.forEach(route=>{
          // 默认情况下，初始权限为已定义或继承上级权限
          let accessible = typeof route.unaccessible === 'boolean' ? !route.unaccessible : parentUnaccessible !== true;
          if ( strictMode ) { // 严格模式下，默认不通过
            accessible = false;
          }
          if ( accessPaths.indexOf( route.absolutePath ) > -1 ) {
            accessible = true;
          }
          route.unaccessible = !accessible;
          if ( route.children && route.children.length ) {
            modifyRoutesByAccessMenus(route.children, accessPaths, strictMode, route.unaccessible)
          }
      })
  }
}